package com.cy.wangly.springcore.custom;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

public class WanglyTypeExcludeFilter implements TypeFilter {
    Logger logger = LoggerFactory.getLogger(WanglyTypeExcludeFilter.class);
    private List<String> exclude;

    private String[] excludeName;

    public WanglyTypeExcludeFilter() {
        init();
    }

    public void init() {
        exclude = null;
        excludeName = null;
        StackTraceElement stack[] = Thread.currentThread().getStackTrace();
        String mainClassName = stack[stack.length - 1].getClassName();
        Class clazz = null;
        try {
            clazz = Class.forName(mainClassName);
        } catch (ClassNotFoundException e) {
            logger.error("main class is not found. className:" + mainClassName);
        }
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            if (annotation.annotationType().equals(WanglyScan.class)) {
                WanglyScan ws = (WanglyScan) annotation;
                if (ws.exclude() != null) {
                    exclude = new ArrayList<String>();
                    for (Class<?> aClass : ws.exclude()) {
                        exclude.add(aClass.getName());
                    }
                }
                excludeName = ws.excludeName();
            }
        }
    }

    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
            throws IOException {
        if (null != exclude) {
            boolean isExclude = exclude.contains(metadataReader.getClassMetadata().getClassName());
            if (isExclude) {
                return true;
            }
        }
        if (null != excludeName || excludeName.length > 0) {
            for (String s : excludeName) {
                PathMatcher pathMatcher = new AntPathMatcher();
                boolean isMatch = pathMatcher.match(s, metadataReader.getClassMetadata().getClassName());
                if (isMatch) {
                    return true;
                }
            }
        }
        return false;
    }
}